package com.xb.system.service.impl;

import com.xb.model.domain.dto.FilterRequestDTO;
import com.xb.system.mapper.db0.UsersMapper;
import com.xb.system.service.FilterService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;
import java.util.Map;

/**
 * 筛选服务实现
 * 
 * @author ruoyi
 */
@Service
@Slf4j
public class FilterServiceImpl implements FilterService {
    
    @Resource
    private UsersMapper usersMapper;
    
    @Override
    public boolean checkMatch(FilterRequestDTO request) {
        try {
            log.info("开始筛选: companyName={}, legalRepresentative={}, phone={}", 
                    request.getCompanyName(), request.getLegalRepresentative(), request.getPhone());
            
            // 提取筛选参数
            String companyName = request.getCompanyName();
            String legalRepresentative = request.getLegalRepresentative();
            String phone = request.getPhone();
            
            // 参数验证：至少需要一个参数
            if ((companyName == null || companyName.trim().isEmpty()) &&
                (legalRepresentative == null || legalRepresentative.trim().isEmpty()) &&
                (phone == null || phone.trim().isEmpty())) {
                log.warn("筛选失败: 所有查询条件都为空");
                return false;
            }
            
            // 清理电话号码（如果提供）
            String cleanPhone = null;
            Integer tableIndex = null;
            String targetTable = null;
            
            if (phone != null && !phone.trim().isEmpty() && !phone.equals("无")) {
                cleanPhone = phone.replaceAll("[^\\d]", "");
                // 根据MurmurHash3算法计算表索引
                tableIndex = getTableIndexByMurmurHash3(cleanPhone);
                targetTable = "data_" + tableIndex;
                log.info("phone={} 计算得到表索引: {}, 目标表: {}", cleanPhone, tableIndex, targetTable);
            }
            
            // 执行匹配查询
            boolean isMatch = false;
            
            if (targetTable != null) {
                // 如果有电话号码，直接在目标表中查询
                List<Map<String, Object>> matches = usersMapper.filterMatch(
                    companyName != null ? companyName.trim() : null,
                    legalRepresentative != null ? legalRepresentative.trim() : null,
                    cleanPhone,
                    targetTable
                );
                isMatch = !matches.isEmpty();
                
                if (isMatch) {
                    log.info("筛选成功: 在表{}中找到匹配记录", targetTable);
                } else {
                    log.info("筛选完成: 在表{}中未找到匹配记录", targetTable);
                }
            } else {
                // 如果没有电话号码，需要在所有表中查询（性能较低）
                log.warn("未提供电话号码，将在所有200个表中查询，性能较低");
                for (int i = 0; i < 200; i++) {
                    String table = "data_" + i;
                    List<Map<String, Object>> matches = usersMapper.filterMatch(
                        companyName != null ? companyName.trim() : null,
                        legalRepresentative != null ? legalRepresentative.trim() : null,
                        null,
                        table
                    );
                    
                    if (!matches.isEmpty()) {
                        isMatch = true;
                        log.info("筛选成功: 在表{}中找到匹配记录", table);
                        break;
                    }
                }
                
                if (!isMatch) {
                    log.info("筛选完成: 在所有表中均未找到匹配记录");
                }
            }
            
            return isMatch;
            
        } catch (Exception e) {
            log.error("筛选失败: ", e);
            return false;
        }
    }
    
    /**
     * 使用MurmurHash3算法计算表索引（与Python脚本保持一致）
     */
    private int getTableIndexByMurmurHash3(String phone) {
        if (phone == null || phone.trim().isEmpty()) {
            return 0;
        }
        
        int hashValue = murmurHash3(phone);
        return Math.abs(hashValue) % 200;
    }
    
    /**
     * MurmurHash3算法实现
     */
    private int murmurHash3(String key) {
        byte[] data = key.getBytes();
        int length = data.length;
        int seed = 0;
        
        int c1 = 0xcc9e2d51;
        int c2 = 0x1b873593;
        int r1 = 15;
        int r2 = 13;
        int m = 5;
        int n = 0xe6546b64;
        
        int hash = seed;
        int nblocks = length / 4;
        
        // body
        for (int i = 0; i < nblocks; i++) {
            int k = getblock(data, i * 4);
            k *= c1;
            k = rotl32(k, r1);
            k *= c2;
            
            hash ^= k;
            hash = rotl32(hash, r2);
            hash = hash * m + n;
        }
        
        // tail
        int tail = nblocks * 4;
        int k1 = 0;
        switch (length & 3) {
            case 3:
                k1 ^= (data[tail + 2] & 0xff) << 16;
            case 2:
                k1 ^= (data[tail + 1] & 0xff) << 8;
            case 1:
                k1 ^= (data[tail] & 0xff);
                k1 *= c1;
                k1 = rotl32(k1, r1);
                k1 *= c2;
                hash ^= k1;
        }
        
        // finalization
        hash ^= length;
        hash = fmix(hash);
        
        return hash;
    }
    
    private int getblock(byte[] data, int i) {
        return ((data[i] & 0xff) | 
                ((data[i + 1] & 0xff) << 8) | 
                ((data[i + 2] & 0xff) << 16) | 
                ((data[i + 3] & 0xff) << 24));
    }
    
    private int rotl32(int x, int r) {
        return (x << r) | (x >>> (32 - r));
    }
    
    private int fmix(int h) {
        h ^= h >>> 16;
        h *= 0x85ebca6b;
        h ^= h >>> 13;
        h *= 0xc2b2ae35;
        h ^= h >>> 16;
        return h;
    }
}

